﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using System.Collections.Generic;
using NanoERP.Infrastructure;
using NanoERP.Model;
using NanoERP.Common;
using NanoERP.Business.BaseInfo;
using NanoERP.Business.BillInfo;
using Microsoft.Practices.Unity;

namespace NanoERP
{
    [Module("FrmSellOut")]
    public partial class FrmSellOut : ModuleForm
    {
        Billinfo _billinfo;
        readonly BillinfoBLL _billinfoBLL;
        readonly SysdictableBLL _sysdictablebLl;
        private const int BillType = 5;

        /// <summary>
        /// 预付定金
        /// </summary>
        decimal _sumPaymoney;

        [InjectionConstructor]
        public FrmSellOut()
        {
            InitializeComponent();

            _billinfo = new Billinfo();
            _sysdictablebLl = new SysdictableBLL();
            _billinfoBLL = new BillinfoBLL();

            _billinfo.CreateuserName = LogonSession.LogonUser.Name;
            BindFormContro();
        }

        public FrmSellOut(Billinfo o)
        {
            InitializeComponent();

            _billinfo = o;
            _sysdictablebLl = new SysdictableBLL();
            _billinfoBLL = new BillinfoBLL();

            BindFormContro();
        }

        /// <summary>
        /// 绑定控件值
        /// </summary>
        void BindFormContro()
        {
            SetToolButtonEnableld((BillStateEnum)_billinfo.State.Value);
            UnitColumn.DisplayMember = "DICNAME";
            UnitColumn.ValueMember = "DICNAME";
            UnitColumn.DataSource = _sysdictablebLl.Query((int)SysDicEnum.基本单位);

            dtPaydate.DataBindings.Add(new Binding("Value", _billinfo, "Paydate", true, DataSourceUpdateMode.OnPropertyChanged));
            dtBilldate.DataBindings.Add(new Binding("Value", _billinfo, "Billdate", true, DataSourceUpdateMode.OnPropertyChanged));
            txtBillno.DataBindings.Add(new Binding("Text", _billinfo, "Billno", true, DataSourceUpdateMode.OnPropertyChanged));
            txtCustomno.DataBindings.Add(new Binding("Text", _billinfo, "Customno", true, DataSourceUpdateMode.OnPropertyChanged));
            txtClientid.DataBindings.Add(new Binding("Text", _billinfo, "ClientName", true, DataSourceUpdateMode.OnPropertyChanged));
            txtClientid.DataBindings.Add(new Binding("Tag", _billinfo, "Clientid", true, DataSourceUpdateMode.OnPropertyChanged));
            txtStorageid.DataBindings.Add(new Binding("Text", _billinfo, "StorageName", true, DataSourceUpdateMode.OnPropertyChanged));
            txtStorageid.DataBindings.Add(new Binding("Tag", _billinfo, "Storageid", true, DataSourceUpdateMode.OnPropertyChanged));
            txtBusiuserid.DataBindings.Add(new Binding("Text", _billinfo, "BusiuserName", true, DataSourceUpdateMode.OnPropertyChanged));
            txtBusiuserid.DataBindings.Add(new Binding("Tag", _billinfo, "Busiuserid", true, DataSourceUpdateMode.OnPropertyChanged));
            nudPaymoney.DataBindings.Clear();
            nudPaymoney.DataBindings.Add(new Binding("Value", _billinfo, "Paymoney", true, DataSourceUpdateMode.OnPropertyChanged));
            txtPayaccount.DataBindings.Add(new Binding("Text", _billinfo, "Payaccount", true, DataSourceUpdateMode.OnPropertyChanged));
            txtInvoicetype.DataBindings.Add(new Binding("Text", _billinfo, "InvoicetypeName", true, DataSourceUpdateMode.OnPropertyChanged));
            txtInvoicetype.DataBindings.Add(new Binding("Tag", _billinfo, "Invoicetype", true, DataSourceUpdateMode.OnPropertyChanged));
            txtNote.DataBindings.Add(new Binding("Text", _billinfo, "Note", true, DataSourceUpdateMode.OnPropertyChanged));
            txtItemname.DataBindings.Add(new Binding("Text", _billinfo, "Itemname", true, DataSourceUpdateMode.OnPropertyChanged));
            nudSummoney.DataBindings.Clear();
            nudSummoney.DataBindings.Add(new Binding("Value", _billinfo, "Summoney", true, DataSourceUpdateMode.OnPropertyChanged));
            nudDerateagion.DataBindings.Clear();
            nudDerateagion.DataBindings.Add(new Binding("Value", _billinfo, "Derateagion", true, DataSourceUpdateMode.OnPropertyChanged));
            nudDeratemoney.DataBindings.Clear();
            nudDeratemoney.DataBindings.Add(new Binding("Value", _billinfo, "Deratemoney", true, DataSourceUpdateMode.OnPropertyChanged));
            nudOughtmoney.DataBindings.Clear();
            nudOughtmoney.DataBindings.Add(new Binding("Value", _billinfo, "Oughtmoney", true, DataSourceUpdateMode.OnPropertyChanged));
            txtCreateuserid.DataBindings.Add(new Binding("Text", _billinfo, "CreateuserName", true, DataSourceUpdateMode.OnPropertyChanged));
            txtCreateuserid.DataBindings.Add(new Binding("Tag", _billinfo, "Createuserid", true, DataSourceUpdateMode.OnPropertyChanged));
            dtCreatedate.DataBindings.Add(new Binding("Value", _billinfo, "Createdate", true, DataSourceUpdateMode.OnPropertyChanged));

            txtExpressid.DataBindings.Add(new Binding("Text", _billinfo, "Express", true, DataSourceUpdateMode.OnPropertyChanged));
            txtExpressid.DataBindings.Add(new Binding("Tag", _billinfo, "Expressid", true, DataSourceUpdateMode.OnPropertyChanged));
            txtExpressno.DataBindings.Add(new Binding("Text", _billinfo, "Expressno", true, DataSourceUpdateMode.OnPropertyChanged));
            nudCarrimoney.DataBindings.Clear();
            nudCarrimoney.DataBindings.Add(new Binding("Value", _billinfo, "Carrimoney", true, DataSourceUpdateMode.OnPropertyChanged));
            nudAgentmoney.DataBindings.Clear();
            nudAgentmoney.DataBindings.Add(new Binding("Value", _billinfo, "Agentmoney", true, DataSourceUpdateMode.OnPropertyChanged));

            isIspaycarri.Checked = _billinfo.Ispaycarri.Value.Equals(1);
            chIspatch.Checked = _billinfo.Ispatch.Value.Equals(1);
            if (_billinfo.ListBilldetail != null)
            {
                dgvList.DataSource = null;
                dgvList.AutoGenerateColumns = false;
                dgvList.DataSource = _billinfo.ListBilldetail;
            }
        }

        private void tsbExport_Click(object sender, EventArgs e)
        {
            string msgLog;
            ExcelUtil.ExportToExcel(dgvList, "销售出库单明细", out msgLog);
            if (msgLog != null)
                MessageBox.Show(msgLog, @"提示消息", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void tsbExit_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void dgvList_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            ControlUtil.DataGridRowPostPaint(sender, e);
        }

        private void btnClientid_Click(object sender, EventArgs e)
        {
            CreateFormView.BindClientForm(txtClientid);
            _billinfo.Clientid = Normal.ToLong(txtClientid.Tag);
        }

        private void btnStorageid_Click(object sender, EventArgs e)
        {
            CreateFormView.BindStorageForm(txtStorageid);
            _billinfo.Storageid = Normal.ToInt(txtStorageid.Tag);
        }

        private void btnBusiuserid_Click(object sender, EventArgs e)
        {
            CreateFormView.BindStaffForm(txtBusiuserid);
            _billinfo.Busiuserid = Normal.ToLong(txtBusiuserid.Tag);
        }

        private void btnPayaccount_Click(object sender, EventArgs e)
        {
            CreateFormView.BindAccountForm(txtPayaccount);

            if (txtPayaccount.Text.Length > 0)
            {
                txtPayaccount.Invoke(new MethodInvoker(() =>
                {
                    var mc = System.Text.RegularExpressions.Regex.Matches(txtPayaccount.Text, @"\s+\d+");
                    nudPaymoney.Value = 0;
                    foreach (System.Text.RegularExpressions.Match m in mc)
                        nudPaymoney.Value += Normal.ToInt(m.Value);

                    _sumPaymoney = nudPaymoney.Value;
                }));
            }
        }

        private void btnItemname_Click(object sender, EventArgs e)
        {
            CreateFormView.BindDepartForm(txtItemname);
        }

        private void nudPaymoney_Leave(object sender, EventArgs e)
        {
            if (nudPaymoney.Value > 0 && nudPaymoney.Value.CompareTo(_sumPaymoney) != 0)
                txtPayaccount.Text = string.Format("现金 {0}", nudPaymoney.Value);
        }

        private void btnInvoicetype_Click(object sender, EventArgs e)
        {
            CreateFormView.BindDicForm(txtInvoicetype, SysDicEnum.发票类型, isSelectRoot: false);
            _billinfo.Invoicetype = Normal.ToInt(txtStorageid.Tag);
        }

        private void buttonX4_Click(object sender, EventArgs e)
        {
            CreateFormView.BindLogisticsForm(txtExpressid);
            _billinfo.Expressid = Normal.ToLong(txtExpressid.Tag);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (txtClientid.Text.Length == 0)
            {
                MessageBox.Show(@"价格跟踪或折扣跟踪模式下请先选择客户！", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                txtClientid.Focus();
                return;
            }
            CreateFormView.BindProductForm(button1, true);
            if (button1.Tag != null)
            {
                var dic = button1.Tag as Dictionary<long, Goodsinfo>;
                if (_billinfo.ListBilldetail == null)
                    _billinfo.ListBilldetail = new List<Billdetail>();

                foreach (var key in dic.Values)
                {
                    _billinfo.ListBilldetail.Add(new Billdetail
                    {
                        Goodsid = key.Id,
                        Storageid = _billinfo.Storageid,
                        Goodsno = key.GoodsNo,
                        Goodsbarcode1 = key.Barcode,
                        Goodsname = key.GoodsName,
                        Goodsspec = key.GoodsSpec,
                        Unit = key.GoodsUnit,
                        Num = 1,
                        Unitprice = key.PriceIn1,
                        Refprice = key.PriceRetail,
                        Agio = 100,
                        Taxrate = 0
                    });
                }

                dgvList.DataSource = null;
                dgvList.AutoGenerateColumns = false;
                dgvList.DataSource = _billinfo.ListBilldetail;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (dgvList.CurrentRow == null) return;
            var row = dgvList.CurrentRow.DataBoundItem as Billdetail;
            if (row.Id == 0) _billinfo.ListBilldetail.Remove(row);
            else
                row.Flag = 1;

            dgvList.DataSource = null;
            dgvList.AutoGenerateColumns = false;
            dgvList.DataSource = _billinfo.ListBilldetail.Where(r => r.Flag.Equals(0)).ToList();
        }

        private void dgvList_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0 || e.ColumnIndex < 0) return;

            Debug.Assert(dgvList.CurrentRow != null, "dgvList.CurrentRow != null");

            var row = dgvList.CurrentRow.DataBoundItem as Billdetail;

            //折扣单价
            dgvList.CurrentRow.Cells["BaseagiopriceColumn"].Value = (row.Agio * row.Baseunitprice) / 100;

            //含税单价
            dgvList.CurrentRow.Cells["BasetaxpriceColumn"].Value = row.Baseagioprice + (row.Taxrate * row.Baseagioprice) / 100;

            //税额
            dgvList.CurrentRow.Cells["TaxmoneyColumn"].Value = (row.Num * row.Taxrate * row.Baseagioprice) / 100;

            //小计
            dgvList.CurrentRow.Cells["SummoneyColumn"].Value = row.Num * row.Basetaxprice;

            nudSummoney.Value = ((List<Billdetail>)dgvList.DataSource).Sum(r => r.Summoney).Value;
        }

        private void tsbAdd_Click(object sender, EventArgs e)
        {
            _billinfo = new Billinfo
            {
                CreateuserName = LogonSession.LogonUser.Name,
                ListBilldetail = new List<Billdetail>()
            };
            ControlUtil.ClearControlBind(panel1);
            ControlUtil.ClearControlBind(panel2);
            ControlUtil.ClearControlBind(panel4);

            BindFormContro();
        }

        private void tsbSave_Click(object sender, EventArgs e)
        {

            if (txtClientid.Text.Length == 0)
            {
                MessageBox.Show(@"数据项[客户]不能为空,请输入！", @"提示信息", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                txtClientid.Focus();
                return;
            }
            if (txtStorageid.Text.Length == 0)
            {
                MessageBox.Show(@"数据项[出货仓库]不能为空,请输入！", @"提示信息", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                txtStorageid.Focus();
                return;
            }

            _billinfo.Summary = string.Empty;
            if (_billinfo.ListBilldetail != null)
                _billinfo.ListBilldetail.Where(r => r.Flag.Equals(0)).ToList()
                         .ForEach(r => _billinfo.Summary += string.Format("{0}{1}{2};", r.Goodsname, r.Num, r.Unit));

            _billinfo.Ispatch = chIspatch.Checked ? 1 : 0;
            _billinfo.Ispaycarri = chIspatch.Checked ? 1 : 0;
            _billinfo.Billtype = BillType;
            _billinfo = _billinfoBLL.Edit(_billinfo);
            txtBillno.Text = _billinfo.Billno;
            MessageBox.Show(@"保存成功.", @"提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void tsbShenhe_Click(object sender, EventArgs e)
        {
            CheckBillState(BillStateEnum.一级审核, "审核");
        }

        private void 反审核ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CheckBillState(BillStateEnum.待审核, "反审");
        }

        private void 作废ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CheckBillState(BillStateEnum.作废, "作废");
        }

        private void CheckBillState(BillStateEnum state, string tip)
        {
            if (_billinfo.Id == 0)
            {
                MessageBox.Show(string.Format("当前业务单据还未保存，不能进行{0}操作", tip), @"提示消息", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                return;
            }

            if (MessageBox.Show(string.Format("确定要{0}当前的业务单据吗？", tip), @"提示消息",
                MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2) == DialogResult.OK)
            {
                _billinfo.State = (int)state;
                _billinfo.Curphasedate = DateTime.Now;
                _billinfo.Curphasename = state.ToString();
                _billinfoBLL.Edit(_billinfo);
                SetToolButtonEnableld(state);
                MessageBox.Show(@"单据操作成功.", @"提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void SetToolButtonEnableld(BillStateEnum state)
        {
            lbState.Text = state.ToString();
            switch (state)
            {
                case BillStateEnum.待审核:
                    tsbSave.Enabled = tsmiCancel.Enabled = tsbShenhe.Enabled =
                        button1.Enabled = button2.Enabled = true;
                    tsmiBack.Enabled = tsmiHc.Enabled = false;
                    break;
                case BillStateEnum.一级审核:
                    tsbSave.Enabled = tsbShenhe.Enabled = tsmiHc.Enabled =
                        button1.Enabled = button2.Enabled = false;
                    tsmiBack.Enabled = tsmiCancel.Enabled = true;
                    break;
                default:
                    tsbSave.Enabled = tsmiCancel.Enabled = tsmiBack.Enabled =
                        tsbShenhe.Enabled = tsmiHc.Enabled = button1.Enabled = button2.Enabled = false;
                    break;
            }
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {

        }

        private void tsbQuery_Click(object sender, EventArgs e)
        {
            WinFormsUI.ActivateOrCreateChildForm(new FrmQueryBill(BillType, Text), DockPanel);
        }

        private void tsbPreRecord_Click(object sender, EventArgs e)
        {
            PreviewRecord(_billinfo.Id - 1, 0);
        }

        private void tsbNextRecord_Click(object sender, EventArgs e)
        {
            PreviewRecord(_billinfo.Id + 1, 1);
        }

        /// <summary>
        /// 浏览记录 上一条 下一条
        /// </summary>
        /// <param name="id">浏览记录Id</param>
        /// <param name="type">类型 0-向上,1-向下</param>
        private void PreviewRecord(long id, int type)
        {
            var isLast = false;
            var obj = _billinfoBLL.PreRecord(id, type, BillType, ref isLast);
            _billinfo = obj;
            ControlUtil.ClearControlBind(panel1);
            ControlUtil.ClearControlBind(panel2);
            ControlUtil.ClearControlBind(panel4);
            BindFormContro();

            if (isLast) MessageBox.Show(string.Format("当前已是{0}一条记录", type.Equals(0) ? "第" : "最后"));
        }
    }
}
